
MBOOT_PAGE_ALIGNED_FLAG		equ	1<<0	; Align all loaded modules to 4kb pages in physical memory.
MBOOT_MEMORY_INFO_FLAG		equ 1<<1	; Pass memory layout info to the kernel.
MBOOT_VIDEO_INFO_FLAG		equ 1<<2	; Set video mode.
MBOOT_HEADER_ADDRESS_FLAG	equ 1<<16	; Where to load the kernel. Not necessary with ELF kernels.
MBOOT_HEADER_MAGIC			equ 0x1BADB002	; Magic number for multiboot.

MBOOT_HEADER_FLAGS equ MBOOT_PAGE_ALIGNED_FLAG | MBOOT_MEMORY_INFO_FLAG ; Which flags to use
MBOOT_HEADER_CHECKSUM equ -(MBOOT_HEADER_MAGIC + MBOOT_HEADER_FLAGS)	; Calculate checksum

KERNEL_PAGE_NUMBER equ 0x300
[bits 32]

section .data
align 0x1000
BootPageDirectory:
	dd 0x0000083
	times(KERNEL_PAGE_NUMBER - 1) dd 0
	dd 0x0000083
	times(1024 - KERNEL_PAGE_NUMBER - 1) dd 0
	
section .text

global mboot
extern code
extern bss
extern end

mboot:							; This is the multiboot header. It tells the bootloader how to load the kernel.
	dd MBOOT_HEADER_MAGIC
	dd MBOOT_HEADER_FLAGS
	dd MBOOT_HEADER_CHECKSUM
	
	dd mboot
	dd code
	dd bss
	dd end
	dd start

global start:function HigherHalf.end-start
extern main

start:

	mov ecx, (BootPageDirectory - 0xC0000000)
	mov cr3, ecx
	
	mov ecx, cr4
	or ecx, 0x00000010
	mov cr4, ecx
	
	mov ecx, cr0
	or ecx, 0x80000000
	mov cr0, ecx
	
	lea ecx, [HigherHalf]
	jmp ecx
	
HigherHalf:	

	mov		esp, initial_stack + 0x2000
	push	esp
	add ebx, 0xC0000000
	push	ebx			; Pass multiboot info to the kernel
	mov	ebp,0
	cli
	call main			; Call main()
	jmp $
.end:

global read_eip
read_eip:
	pop eax
	jmp eax

global spin
spin:
	mov edx, [esp + 4]
	mov eax, 0 
	mov ecx, 1
.retry:
	lock cmpxchg [edx], cl
	jnz .retry
ret

section .bss
align 32

initial_stack:
	resb 0x2000
global kernel_stack
kernel_stack:
	resb 0x2000
